/*
 * Copyright (c) 2014 Strong Group - 版权所有
 * 
 * This software is the confidential and proprietary information of
 * Strong Group. You shall not disclose such confidential information 
 * and shall use it only in accordance with the terms of the license 
 * agreement you entered into with www.cnstrong.cn.
 */
package com.zuorenke.help;


import com.zuorenke.encrypt.EncryptUtils;
import com.zuorenke.model.constants.StringCsts;

import java.io.IOException;
import java.util.Random;

/**
 *
 * 描述:Ticket加密工具类
 *
 * @author  WQB
 * @created 2014-4-4 下午2:58:39
 * @since   v1.0.0
 */
public class TicketEncrypt {

	private static final Random RDM = new Random();
	private static final int MAX_CHAR_SHIFT = 32;

	/**
	 * 加密
	 * 
	 * @param source
	 * @return
	 */
	public static String encode(String source) {
		int seed = RDM.nextInt(MAX_CHAR_SHIFT);
		StringBuilder content = shift(appendConfusions(source), seed)
				.reverse();
		StringBuilder sb = new StringBuilder();
		sb.append(encodeSeed(seed));
		sb.append(StringCsts.SEMICOLON_SEPARATOR);
		sb.append(EncryptUtils.encodeBase64(content.toString()));
		sb.append(StringCsts.SEMICOLON_SEPARATOR);
		sb.append(seed);
		sb.append(seed);
		return EncryptUtils.encodeBase64(sb.toString());
	}

	private static String encodeSeed(int seed) {
		return EncryptUtils.encodeBase64(EncryptUtils.encodeBase64("" + seed));
	}

	private static StringBuilder appendConfusions(String source) {
		StringBuilder sb = new StringBuilder(source);
		for (int i = 0, len = source.length(); i < len; i += 2) {
			sb.append(source.charAt(i));
		}
		return sb;
	}

	private static StringBuilder shift(CharSequence chars, int seed) {
		StringBuilder sb = new StringBuilder();
		int sft = seed % MAX_CHAR_SHIFT;
		for (int i = 0; i < chars.length(); i++) {
			char ch = chars.charAt(i);
			int charCode = ch ^ sft;
			sb.append((char) charCode);
		}
		return sb;
	}

	/**
	 * 破解
	 * 
	 * @param source
	 * @return
	 * @throws IOException
	 */
	public static String decode(String source) {
		if (StringUtils.isEmpty(source)) {
			throw new IllegalArgumentException("ticket error, ticket is empty");
		}

		String decoded = null;
		try {
			decoded = EncryptUtils.decodeBase64ToString(source);
			String[] tuple = decoded.split(StringCsts.SEMICOLON_SEPARATOR);
			int random = decodeSeed(tuple[0]);
			String temp = EncryptUtils.decodeBase64ToString(tuple[1]);
			StringBuilder content = shift(temp, random).reverse();
			int len = content.length() * 2 / 3;
			return content.substring(0, len).toString();
		} catch (Exception e) {
			throw new IllegalArgumentException("非法操作，请重新登录！Ticket error,ticket is "
					+ source + ". decode:" + decoded, e);
		}
	}

	private static int decodeSeed(String source) {
		return Integer.parseInt(EncryptUtils.decodeBase64ToString(EncryptUtils
				.decodeBase64ToString(source)));
	}
}
